package PodsumowaniaLingwistyczne;

import java.util.LinkedList;
import java.util.List;

import PrzestrzenCiagla.CiaglyZbiorRozmyty;
import csvIO.CsvObject;
import csvIO.CsvRow;

public class Miary {

	public static float in(CiaglyZbiorRozmyty zbior) {
		float miaraPrzestrzeni = zbior.getPrzestrzen().getDlugosc();
		float miaraNosnika = zbior.dlugoscNosnika();
		return miaraNosnika / miaraPrzestrzeni;
	}

	public static float ocen(Podsumowanie podsumowanie, CsvObject bazaDanych, float[] wagi) {
		float[] ocena = podsumowanie.getOcena();
		ocena[1] = T1(podsumowanie, bazaDanych);
		ocena[2] = T2(podsumowanie.getSumaryzator());
		ocena[3] = T3(podsumowanie, bazaDanych);
		ocena[4] = T4zT3(podsumowanie, bazaDanych);
		ocena[5] = T5(podsumowanie);
		ocena[6] = T6(podsumowanie.getKwantyfikator());
		ocena[7] = T7(podsumowanie.getKwantyfikator());
		ocena[8] = T8(podsumowanie.getSumaryzator());
		ocena[9] = T9(podsumowanie.getKwalifikator());
		ocena[10] = T10(podsumowanie.getKwalifikator());
		ocena[11] = T11(podsumowanie);

		for (int i = 1; i < 12; i++) {
			ocena[0] += wagi[i] * ocena[i];
		}

		return ocena[0];
	}

	public static List<Podsumowanie> podsumowaniaZJednymSumaryzatorem(Podsumowanie podsumowanie) {
		List<Podsumowanie> lista = new LinkedList<Podsumowanie>();
		List<ISumaryzator> listaSumaryzatorow = podsumowanie.getSumaryzator().getSumaryzatorySkladowe();
		for (ISumaryzator sumaryzator : listaSumaryzatorow) {
			lista.add(new Podsumowanie(sumaryzator, podsumowanie.getKwantyfikator()));
		}
		return lista;
	}

	public static float rc(CiaglyZbiorRozmyty zbior) {
		float rc = zbior.getClm() / zbior.getPrzestrzen().getDlugosc();
		return rc;
	}

	public static float T1(Podsumowanie podsumowanie, CsvObject bazaDanych) {
		if (podsumowanie.getKwalifikator() != null) {
			return t1Kwal(podsumowanie, bazaDanych);
		} else {
			return t1BezKwal(podsumowanie, bazaDanych);
		}
	}

	public static float T10(IKwalifikator kwalifikator) {
		if (kwalifikator != null) {
			float iloczyn = 1.0f;
			List<IKwalifikator> lista = kwalifikator.getKwalifikatorySkladowe();

			for (IKwalifikator kwal : lista) {
				iloczyn *= rc(kwal.getWartoscLingwistyczna().getZbior());
			}

			float t10 = (float) (1.0 - Math.pow((double) iloczyn, 1.0 / (double) lista.size()));
			return t10;
		} else {
			return 0;
		}
	}

	public static float T11(Podsumowanie podsumowanie) {
		IKwalifikator kwal = podsumowanie.getKwalifikator();
		if (kwal == null) {
			return 0.0f;
		}
		List<IKwalifikator> lista = kwal.getKwalifikatorySkladowe();
		float t11 = (float) (2.0 * Math.pow(0.5, (double) lista.size()));
		return t11;
	}

	private static float t1BezKwal(Podsumowanie podsumowanie, CsvObject bazaDanych) {
		float r = 0.0f;
		ISumaryzator sumaryzator = podsumowanie.getSumaryzator();

		for (CsvRow krotka : bazaDanych.getRows()) {
			r += sumaryzator.getPrzynaleznosc(krotka);
		}

		Kwantyfikator kwantyfikator = podsumowanie.getKwantyfikator();
		float t1;
		if (kwantyfikator.isCzyAbsolutny()) {
			t1 = kwantyfikator.getPrzynaleznosc(r);
		} else {
			float m = bazaDanych.getRowsCount();
			t1 = kwantyfikator.getPrzynaleznosc(r / m);
		}

		return t1;
	}

	private static float t1Kwal(Podsumowanie podsumowanie, CsvObject bazaDanych) {
		float r = 0.0f;
		float m = 0.0f;

		IKwalifikator kwalifikator = podsumowanie.getKwalifikator();
		ISumaryzator sumaryzator = podsumowanie.getSumaryzator();

		for (CsvRow krotka : bazaDanych.getRows()) {
			float kwalPrzyn = kwalifikator.getPrzynaleznosc(krotka);
			m += kwalPrzyn;
			r += Math.min(sumaryzator.getPrzynaleznosc(krotka), kwalPrzyn);
		}

		Kwantyfikator kwantyfikator = podsumowanie.getKwantyfikator();
		float t1;
		if (kwantyfikator.isCzyAbsolutny()) {
			t1 = kwantyfikator.getPrzynaleznosc(r);
		} else {
			t1 = kwantyfikator.getPrzynaleznosc(r / m);
		}

		return t1;
	}

	public static float T2(ISumaryzator sumaryzator) {
		float iloczyn = 1.0f;
		List<ISumaryzator> lista = sumaryzator.getSumaryzatorySkladowe();

		for (ISumaryzator sumar : lista) {
			iloczyn *= in(sumar.getWartoscLingwistyczna().getZbior());
		}

		float t2 = (float) (1.0 - Math.pow((double) iloczyn, 1.0 / (double) lista.size()));
		return t2;
	}

	public static float T3(Podsumowanie podsumowanie, CsvObject bazaDanych) {
		int iloscKrotekSpelniajacychSumaryzator = podsumowanie.iloscKrotekSpelniajacychSumaryzator(bazaDanych);
		int iloscKrotekSpelniajacychKwalifikator = podsumowanie.getIloscKrotekSpelniajacychKwalifikator(bazaDanych);

		float t3 = (float) iloscKrotekSpelniajacychSumaryzator / (float) iloscKrotekSpelniajacychKwalifikator;
		return t3;
	}

	private static float t4(Podsumowanie podsumowanie, CsvObject bazaDanych, float t3) {
		List<Podsumowanie> listaPodsumowan = podsumowaniaZJednymSumaryzatorem(podsumowanie);
		float iloczyn = 1.0f;
		for (Podsumowanie podsum : listaPodsumowan) {
			int m = bazaDanych.getRowsCount();

			float r = (float) podsum.iloscKrotekSpelniajacychSumaryzator(bazaDanych) / (float) m;
			iloczyn *= r;
		}

		float t4 = Math.abs(iloczyn - t3);
		return t4;
	}

	public static float T4bezT3(Podsumowanie podsumowanie, CsvObject bazaDanych) {
		float t4bezt3 = t4(podsumowanie, bazaDanych, 0.0f);
		return t4bezt3;
	}

	public static float T4zT3(Podsumowanie podsumowanie, CsvObject bazaDanych) {
		float t4zt3 = t4(podsumowanie, bazaDanych, T3(podsumowanie, bazaDanych));
		return t4zt3;
	}

	public static float T5(Podsumowanie podsumowanie) {
		List<ISumaryzator> lista = podsumowanie.getSumaryzator().getSumaryzatorySkladowe();
		float t5 = (float) (2.0 * Math.pow(0.5, (double) lista.size()));
		return t5;
	}

	public static float T6(Kwantyfikator kwantyfikator) {
		float t6 = (float) (1.0 - in(kwantyfikator.getZbior()));
		return t6;
	}

	public static float T7(Kwantyfikator kwantyfikator) {
		float t7 = (float) (1.0f - rc(kwantyfikator.getZbior()));
		return t7;
	}

	public static float T8(ISumaryzator sumaryzator) {
		float iloczyn = 1.0f;
		List<ISumaryzator> lista = sumaryzator.getSumaryzatorySkladowe();

		for (ISumaryzator sumar : lista) {
			iloczyn *= rc(sumar.getWartoscLingwistyczna().getZbior());
		}

		float t8 = (float) (1.0 - Math.pow((double) iloczyn, 1.0 / (double) lista.size()));
		return t8;
	}

	public static float T9(IKwalifikator kwalifikator) {
		if (kwalifikator != null) {
			float iloczyn = 1.0f;
			List<IKwalifikator> lista = kwalifikator.getKwalifikatorySkladowe();

			for (IKwalifikator kwal : lista) {
				iloczyn *= in(kwal.getWartoscLingwistyczna().getZbior());
			}

			float t9 = (float) (1.0 - Math.pow((double) iloczyn, 1.0 / (double) lista.size()));
			return t9;
		} else {
			return 0;
		}
	}

}
